我們在昨天介紹了如何使用 sync.WaitGroup 來進行 Goroutines
今天要來介紹 sync 的另外一個,叫做 sync.Mutex,中文叫做互斥鎖
當同時有很多個 Goroutines 要對一個變數進行修改時,透過使用 Lock()
和 Unlock()
這兩個 method,就可以有效的避免掉資源競爭的問題
下面我們就來玩看看吧~
// 宣告一個 Mutex 互斥鎖
var mu sync.Mutex
/*
Lock() 與 Unlock() 是成雙成對的
有 Lock() 就一定要進行 Unlock()
不然的話,會造成 Deadlock,因為阻塞了
*/
// 告訴系統說,對當前的 Goroutines 進行上鎖
// 確保只有當前的 Goroutines 可以對該資源進行存取
mu.Lock()
// 告訴系統說,對當前的 Goroutines 進行解鎖
// 開放其他的 Goroutines 可以對該資源進行存取
mu.Unlock()
下面就用 A Tour of Go 上的官方範例來進行講解
package main
import (
"fmt"
"sync"
"time"
)
// SafeCounter is safe to use concurrently.
type SafeCounter struct {
mu sync.Mutex
v map[string]int
}
// Inc increments the counter for the given key.
func (c *SafeCounter) Inc(key string) {
c.mu.Lock()
// Lock so only one goroutine at a time can access the map c.v.
c.v[key]++
c.mu.Unlock()
}
// Value returns the current value of the counter for the given key.
func (c *SafeCounter) Value(key string) int {
c.mu.Lock()
// Lock so only one goroutine at a time can access the map c.v.
defer c.mu.Unlock()
return c.v[key]
}
func main() {
c := SafeCounter{v: make(map[string]int)}
for i := 0; i < 1000; i++ {
go c.Inc("somekey")
}
time.Sleep(time.Second)
fmt.Println(c.Value("somekey"))
}
SafeCounter
struct,結構內包含 Mutex 與 map 變數 v
-> Line 10~13
SafeCounter
struct 的 method Inc(key string)
-> Line 16~21
SafeCounter
struct 的 method Value(key string)
-> Line 24~29
*SafeCounter
receiver c 的 Mutex mu
將當前的 Goroutines 上鎖 Lock()
-> Line 17
*SafeCounter
receiver c 的 map v
對應 key 的 value 進行修改 -> Line 19
*SafeCounter
receiver c 的 Mutex mu
將當前的 Goroutines 解鎖 Unlock()
-> Line 20
*SafeCounter
receiver c 的 Mutex mu
將當前的 Goroutines 上鎖 Lock()
-> Line 25
*SafeCounter
receiver c 的 map v
對應 key 的 value -> Line 28
defer
,使用 *SafeCounter
receiver c 的 Mutex mu
將當前的 Goroutines 解鎖 Unlock()
-> Line 27
SafeCounter
的變數 c
-> Line 32
c.Inc("somekey")
-> Line 33~35
c
裡 map["somekey"] 的對應值,並輸出 -> Line 38
如果將 func (c *SafeCounter) Inc(key string)
裡面的 c.mu.Lock()
與 c.mu.Unlock()
註解掉,會發生什麼事呢?
今天簡單介紹了 Goroutines 中 sync.Mutex 的用法
Go 基礎就到這邊先告一段落了,接下來要來開始介紹如何使用 Go 架設後端服務,以及...
明天開始要來介紹,Go 要如何連接 SQL 資料庫~
明天見~